﻿using System;
using System.Collections.Generic;
using System.Linq;
using ValidationFramework.Web.MVC.Interfaces;

namespace ValidationFramework.Web.MVC
{
	public class PropertyToElementConverter : IRuleConverter
	{
	    readonly IDictionary<Type, IClientScriptProvider> scriptProviders;

		/// <summary>
		/// Initializes a new instance of the RuleConverter class.
		/// </summary>
		public PropertyToElementConverter()
		{
			scriptProviders = ClientScriptProviders.ScriptProviders;
		}
		/// <summary>
		/// Initializes a new instance of the MapPropertyToElementRuleConverter class.
		/// </summary>
		/// <param name="scriptProviders"></param>
		public PropertyToElementConverter(IDictionary<Type, IClientScriptProvider> scriptProviders)
		{
			this.scriptProviders = scriptProviders;
		}

		#region IRuleConverter Members

		public FormRuleDictionary ConvertToClientRules(IList<PropertyRuleInfo> rules)
		{
			var rulesByProperty = from ruleInfo in rules
			                      group ruleInfo by ruleInfo.PropertyName into g
			                      select g;

			var formRules = new FormRuleDictionary();
			foreach (var group in rulesByProperty)
			{
				var elementRules = new List<IElementRule>();

				foreach (var item in group)
				{
					var rule = item.Rule;
					// If this rule has a script provider
					if (scriptProviders.ContainsKey(rule.GetType()))
					{
						var scriptProvider = scriptProviders[rule.GetType()];
						elementRules.Add(new ElementRule()
						{
							ErrorMessage = rule.ErrorMessage,
							FunctionName = scriptProvider.GetFunctionName(rule),
							Arguments = scriptProvider.GetFunctionArguments(rule).ToArray()
						});
					}
				}
				if (elementRules.Count > 0)
				{
                    formRules.Add(group.Key, elementRules); // assume the form input id is the same as the property
                }
			}

			return formRules;
		}

		#endregion
	}
}
